#ifndef QSLOGDESTFILE_H
#define QSLOGDESTFILE_H

#include "QsLogDest.h"
#include <QFile>
#include <QTextStream>
#include <QtGlobal>
#include <QSharedPointer>

namespace QsLogging
{
class RotationStrategy
{
public:
    // 虚析构函数
    virtual ~RotationStrategy();

    // 设置初始文件信息
    virtual void setInitialInfo(const QFile &file) = 0;
    // 在计算中包含消息大小
    virtual void includeMessageInCalculation(const QString &message) = 0;
    // 判断是否应该轮转
    virtual bool shouldRotate() = 0;
    // 执行轮转操作
    virtual void rotate() = 0;
    // 获取推荐的文件打开模式
    virtual QIODevice::OpenMode recommendedOpenModeFlag() = 0;
};

// 从不轮转文件，覆盖现有文件。
class NullRotationStrategy : public RotationStrategy
{
public:
    // 设置初始信息（空实现）
    void setInitialInfo(const QFile &) override {}
    // 包含消息计算（空实现）
    void includeMessageInCalculation(const QString &) override {}
    // 判断是否轮转（总是返回false）
    bool shouldRotate() override { return false; }
    // 执行轮转（空实现）
    void rotate() override {}
    // 获取打开模式（截断模式）
    QIODevice::OpenMode recommendedOpenModeFlag() override { return QIODevice::Truncate; }
};

// 在达到大小后轮转，保留 <= 10 个备份，追加到现有文件。
class SizeRotationStrategy : public RotationStrategy
{
public:
    // 构造函数
    SizeRotationStrategy();
    static const int MaxBackupCount;

    // 设置初始文件信息
    void setInitialInfo(const QFile &file) override;
    // 在计算中包含消息大小
    void includeMessageInCalculation(const QString &message) override;
    // 判断是否应该轮转
    bool shouldRotate() override;
    // 执行轮转操作
    void rotate() override;
    // 获取推荐的文件打开模式
    QIODevice::OpenMode recommendedOpenModeFlag() override;

    // 设置最大文件大小（字节）
    void setMaximumSizeInBytes(qint64 size);
    // 设置备份文件数量
    void setBackupCount(int backups);

private:
    QString mFileName;
    qint64 mCurrentSizeInBytes;
    qint64 mMaxSizeInBytes;
    int mBackupsCount;
};

typedef QSharedPointer<RotationStrategy> RotationStrategyPtr;

// 文件消息接收器
class FileDestination : public Destination
{
public:
    // 构造函数，指定文件路径和轮转策略
    FileDestination(const QString& filePath, RotationStrategyPtr rotationStrategy);
    // 写入日志消息到文件
    void write(const QString& message, Level level) override;
    // 检查文件目标是否有效
    bool isValid() override;

private:
    QFile mFile;
    QTextStream mOutputStream;
    QSharedPointer<RotationStrategy> mRotationStrategy;
};

}

#endif // QSLOGDESTFILE_H
